package decoder

import (
	"bytes"
	"encoding/binary"
	"git.gz.internal.jumaiyx.cn/pkg/tnet/buffer"
	"git.gz.internal.jumaiyx.cn/pkg/tnet/pack"
	"sync"
)

type FrameDecoder interface {
	Decoder(buff []byte) [][]byte
}

// FrameDecoder 数据包解码器
type frameDecoder struct {
	FinalOffset    int              // 最后的偏移量
	MaxFrameLength int              // 每帧最大的长度
	FieldLength    int              // 头标长度的字节数
	IdLength       int              // ID长度的字节数
	in             []byte           // 数据包
	Order          binary.ByteOrder // 大小端
	lock           sync.Mutex
}

func NewFrameDecoder() FrameDecoder {
	return &frameDecoder{
		FinalOffset:    0,
		MaxFrameLength: 2048,
		FieldLength:    pack.FieldLength,
		IdLength:       pack.IdLength,
		//Order:          binary.LittleEndian,
		Order: buffer.ByteOrder,
	}
}

func (fd *frameDecoder) Decoder(buff []byte) [][]byte {
	fd.lock.Lock()
	defer fd.lock.Unlock()
	fd.in = append(fd.in, buff...)
	resp := make([][]byte, 0)
	for {
		//fmt.Println("===============")
		//fmt.Println("原：", fd.in)
		in := fd.decode(fd.in)
		if in == nil {
			return resp
		}

		resp = append(resp, in)
		//fmt.Println("终：", fd.in)
		//fmt.Println("fd.FinalOffset:", fd.FinalOffset)
		if fd.FinalOffset != 0 {
			fd.in = fd.in[fd.FinalOffset:]
			//fmt.Println("后：", fd.in)
			fd.FinalOffset = 0
		}
	}
}

func (fd *frameDecoder) decode(buff []byte) []byte {
	in := bytes.NewBuffer(buff)
	if in.Len() == 0 || in.Len() < fd.FinalOffset {
		//说明长度字段的包都还不完整或者半包
		return nil
	}
	// 1.截取帧的长度
	frameLength := fd.getFrameLength(in)
	// 2.如果数据帧小于0，是个异常包直接丢掉
	if frameLength < 0 {
		return nil
	}
	dataTotalLength := int(frameLength + uint64(fd.FieldLength+fd.IdLength))
	// 如果数据包长度大于最大长度，截取处理
	if dataTotalLength > fd.MaxFrameLength {
		fd.FinalOffset = fd.FinalOffset + dataTotalLength
		return fd.excessFrameLength(in, dataTotalLength)
	}
	// 3.半包先不处理
	if len(buff) < dataTotalLength {
		return nil
	}
	buf := make([]byte, fd.FinalOffset+dataTotalLength)
	//4. 如果总数据包长度大于，
	// 是：截取包的长度处于黏包状态
	// 否：不存在黏包
	if len(buff) > dataTotalLength {
		copy(buf, buff[fd.FinalOffset:fd.FinalOffset+dataTotalLength])
		fd.FinalOffset = fd.FinalOffset + dataTotalLength
	}
	if len(buff) == dataTotalLength {
		fd.FinalOffset = dataTotalLength
		//buf = buff
		copy(buf, buff)
	}
	// 5.解析包信息体
	return buf
}

func (fd *frameDecoder) getFrameLength(buf *bytes.Buffer) uint64 {
	arr := buf.Bytes()
	arr = arr[fd.FinalOffset : fd.FinalOffset+fd.FieldLength]
	//fmt.Println(arr)
	//fmt.Println("111:", buffer.ByteOrder.Uint32(arr))
	//buff := bytes.NewBuffer(arr)
	//var value uint32
	//err := binary.Read(buff, fd.Order, &value)
	//if err != nil {
	//	log.Fatal(err)
	//}
	return uint64(buffer.ByteOrder.Uint32(arr))
}

func (fd *frameDecoder) excessFrameLength(buff *bytes.Buffer, length int) []byte {
	// 数据包还没有完全传输完成的确实的情况下，暂时忽略等待数据填充完成
	if length > buff.Len() {
		return nil
	}
	in := buff.Bytes()
	if buff.Len() > length {
		in = in[:length]
	}
	in = in[:fd.MaxFrameLength]
	return in
}
